package com.xiangxiao.rpan.storage.threadpool;

/**
 * @auther xiangxiao
 * @email 573768011@qq.com
 * @data 2023/8/18 11:36
 */
/**
 * 线程执行调度框架(自定义线程池)
 * */
import com.google.common.util.concurrent.ThreadFactoryBuilder;

import java.util.List;
import java.util.concurrent.*;

/**
 * 线程执行调度框架(自定义线程池)
 * */

public class ThreadExecutorUtils {
  private ThreadExecutorUtils() {
  }

  private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
  // 核心线程数量大小
  private static final int corePoolSize = CPU_COUNT * 2;
  // 线程池最大容纳线程数
  private static final int maxiPoolSize = corePoolSize * 2;
  // 任务过多后，存储任务的阻塞队列大小  Integer.MAX_VALUE; 2^31 - 1 = 2147483647
  private static final int capacity = Integer.MAX_VALUE;

  private static ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("Thread-pool-%d").build();

  /**
   * 线程池任务满载后采取的任务拒绝策略
   * AbortPolicy 丢弃任务，抛出异常(默认)
   * CallerRunsPolicy 直接执行当前任务
   * DiscardPolicy 丢弃任务，但是不抛出异常
   * DiscardOldestPolicy 丢弃队列最前面的任务，然后重新尝试执行任务（重复此过程）
   */
  private static RejectedExecutionHandler rejectHandler = new ThreadPoolExecutor.CallerRunsPolicy();

  public static ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maxiPoolSize, 0L,
      TimeUnit.SECONDS, new LinkedBlockingQueue<>(capacity), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());

  /**
   * 线程池，io密集型
   */
  public static ThreadPoolExecutor executorCpu = new ThreadPoolExecutor(CPU_COUNT + 1, corePoolSize + 1, 10L,
      TimeUnit.SECONDS, new LinkedBlockingQueue<>(capacity), rejectHandler);

  /**
   * 无返回任务执行
   *
   * @param runnable 任务
   */
  public static void execute(Runnable runnable) {
    executor.execute(runnable);
  }

  /**
   * 有结果的返回
   *
   * @param callable 任务
   * @param <V>      v
   * @return 结果
   */
  public static <V> Future<V> call(Callable<V> callable) {
    return executor.submit(callable);
  }

  public static Future<?> submit(Runnable task) {
    return executor.submit(task);
  }

  /**
   * 调用批量任务
   *
   * @param tasks 任务
   * @param <V>   v
   * @return 结果
   */
  public static <V> List<Future<V>> invokeAll(List<Callable<V>> tasks) {
    try {
      return executor.invokeAll(tasks);
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
      e.printStackTrace();
    }
    return null;
  }
}
